<?php
namespace Sdk\Order\Adapter\AmazonFTL;

use Marmot\Core;
use Marmot\Interfaces\INull;
use Marmot\Interfaces\IRestfulTranslator;

use Sdk\Common\Model\Interfaces\IOperateAble;
use Sdk\Common\Adapter\CommonRestfulAdapter;

use Sdk\Common\Adapter\Traits\MapErrorsTrait;
use Sdk\Common\Adapter\Traits\FetchAbleRestfulAdapterTrait;
use Sdk\Common\Adapter\Traits\OperateAbleRestfulAdapterTrait;

use Sdk\Order\Model\AmazonFTL;
use Sdk\Order\Model\NullAmazonFTL;
use Sdk\Order\Translator\AmazonFTLRestfulTranslator;

use Sdk\Order\Model\NullOrderPriceReport;
use Sdk\Order\Translator\OrderPriceReportRestfulTranslator;

use Sdk\Application\ParseTask\Model\ParseTask;
use Sdk\Application\ParseTask\Model\NullParseTask;
use Sdk\Application\ParseTask\Translator\ParseTaskRestfulTranslator;

class AmazonFTLRestfulAdapter extends CommonRestfulAdapter implements IAmazonFTLAdapter
{
    use FetchAbleRestfulAdapterTrait,
        OperateAbleRestfulAdapterTrait,
        MapErrorsTrait;

    const MAP_ERROR = array(
        100001 => array(
            'isaNumber' => ISA_NUMBER_FORMAT_INCORRECT,//isa格式错误
            'pickupDate' => PICKUP_DATE_FORMAT_INCORRECT,//取货日期格式错误
            'readyTime' => READY_TIME_FORMAT_INCORRECT,//取货时间格式错误
            'closeTime' => CLOSE_TIME_FORMAT_INCORRECT,//下班时间格式错误
            'pickupNumber' => PICKUP_NUMBER_FORMAT_INCORRECT,//取货码格式错误
            'remark' => REMARK_FORMAT_INCORRECT,//备注格式错误
            'items' => ITEMS_FORMAT_INCORRECT,//货物信息格式错误
            'pickupAddressType' => PICKUPADDRESSTYPE_FORMAT_INCORRECT,//发货地址类型格式错误
            'deliveryAddressType' => DELIVERYADDRESSTYPE_FORMAT_INCORRECT,//送货地址类型格式错误
            'price' => PRICE_FORMAT_INCORRECT,//价格格式（一般为priceApiIdentify没有正确匹配）不正确，请重新输入
        ),
        100002 => array(
            'amazonFTL' => AMAZONFTL_CAN_NOT_MODIFY,//整板订单不能操作(订单状态不对)|403
        ),
        100004 => array(
            'staff' => USER_IDENTITY_AUTHENTICATION_FAILED,//后台用户不存在
            'member' => USER_IDENTITY_AUTHENTICATION_FAILED,//官网用户不存在
            'address' => ADDRESS_NOT_EXISTS,//地址不存在|404
            'pickupWarehouse' => PICKUPWAREHOUSE_NOT_EXISTS,//取货仓库不存在|404
            'targetWarehouse' => TARGETWAREHOUSE_NOT_EXISTS,//目标仓库不存在|404
        ),
        100005 => RESOURCE_NOT_EXISTS,//主体不存在
        100400 => array(
            'amazonFTL' => AMAZONFTL_HAVE_BEEN_FROZEN,//整板订单被冻结|403
        ),
        100413 => array(
            'name' => FILE_PARSING_FAILED,//文件解析失败|403
        ),
        100414 => array(
            'name' => THE_NUMBER_OF_PARSES_EXCEEDS_THE_LIMIT,//解析数量超过限制(目前限制为100条)|403
        ),
        100415 => array(
            'name' => FILE_PARSING_RETURNED_NULL,//文件解析返回空|403
        ),
        100421 => INTERFACE_QUOTATION_NOT_MATCHED,//未匹配到接口报价
    );
    
    const SCENARIOS = [
        'AMAZONFTL_LIST'=>[
            'fields' => [],
            'include' => ''
        ],
        'AMAZONFTL_FETCH_ONE'=>[
            'fields'=>[],
            'include'=>''
        ]
    ];

    public function __construct(string $baseurl = '', array $headers = [])
    {
        parent::__construct(
            new AmazonFTLRestfulTranslator(),
            'amazonFTL',
            $baseurl,
            $headers
        );
    }

    protected function getNullObject() : INull
    {
        return NullAmazonFTL::getInstance();
    }

    protected function getAlonePossessMapErrors() : array
    {
        return self::MAP_ERROR;
    }

    public function scenario($scenario) : void
    {
        $this->scenario = isset(self::SCENARIOS[$scenario]) ? self::SCENARIOS[$scenario] : array();
    }

    public function insert(IOperateAble $operateAbleObject) : bool
    {
        $keys = $this->insertTranslatorKeys();
        $data = $this->getTranslator()->objectToArray($operateAbleObject, $keys);

        $this->post(
            'memberOrders/amazonFTL',
            $data
        );
        
        if ($this->isSuccess()) {
            $this->translateToObject($operateAbleObject);
            return true;
        }

        return false;
    }

    public function update(IOperateAble $operateAbleObject) : bool
    {
        $keys = $this->updateTranslatorKeys();
        $data = $this->getTranslator()->objectToArray($operateAbleObject, $keys);

        $this->patch(
            'memberOrders/amazonFTL/'.$operateAbleObject->getMemberOrder()->getId(),
            $data
        );
        
        if ($this->isSuccess()) {
            $this->translateToObject($operateAbleObject);
            return true;
        }

        return false;
    }
    
    protected function insertTranslatorKeys() : array
    {
        return array(
            'pickupWarehouse',
            'targetWarehouse',
            'address',
            'items',
            'pickupDate',
            'readyTime',
            'closeTime',
            'pickupNumber',
            'remark',
            'pickupAddressType',
            'deliveryAddressType',
            'priceApiRecordId',
            'priceApiIdentify',
            'member',
            'staff'
        );
    }

    protected function updateTranslatorKeys() : array
    {
        return array(
            'pickupWarehouse',
            'targetWarehouse',
            'address',
            'items',
            'pickupDate',
            'readyTime',
            'closeTime',
            'pickupNumber',
            'remark',
            'pickupAddressType',
            'deliveryAddressType',
            'priceApiRecordId',
            'priceApiIdentify',
            'member',
            'staff'
        );
    }

    protected function enableTranslatorKeys() : array
    {
        return array();
    }

    protected function disableTranslatorKeys() : array
    {
        return array();
    }

    protected function deletedTranslatorKeys() : array
    {
        return array();
    }

    public function memberCancel(AmazonFTL $amazonFTL) : bool
    {
        $data = $this->getTranslator()->objectToArray($amazonFTL, array('member'));
        unset($data['data']['attributes']);

        $this->patch(
            $this->getResource().'/'.$amazonFTL->getId().'/cancel',
            $data
        );
        
        if ($this->isSuccess()) {
            $this->translateToObject($amazonFTL);
            return true;
        }

        return false;
    }

    public function staffCancel(AmazonFTL $amazonFTL) : bool
    {
        $data = $this->getTranslator()->objectToArray($amazonFTL, array('staff'));
        unset($data['data']['attributes']);

        $this->patch(
            $this->getResource().'/'.$amazonFTL->getId().'/cancel',
            $data
        );
        
        if ($this->isSuccess()) {
            $this->translateToObject($amazonFTL);
            return true;
        }

        return false;
    }

    public function confirm(AmazonFTL $amazonFTL) : bool
    {
        $data = $this->getTranslator()->objectToArray($amazonFTL, array('staff'));
        unset($data['data']['attributes']);
       
        $this->patch(
            $this->getResource().'/'.$amazonFTL->getId().'/confirm',
            $data
        );
        
        if ($this->isSuccess()) {
            $this->translateToObject($amazonFTL);
            return true;
        }

        return false;
    }

    public function batchConfirm(array $amazonFTLList) : bool
    {
        foreach ($amazonFTLList as $amazonFTL) {
            $amazonFTLData[] = array(
                'type' => 'amazonFTL',
                'id' => strval($amazonFTL->getId())
            );

            $data = $this->getTranslator()->objectToArray($amazonFTL, array('staff'));
            unset($data['data']['attributes']);
        }

        $data['data']['relationships']['amazonFTL']['data'] = $amazonFTLData;

        $this->patch(
            $this->getResource().'/batchConfirm',
            $data
        );
        
        if ($this->isSuccess()) {
            $this->translateToObjects();
            return true;
        }

        return false;
    }

    public function freeze(AmazonFTL $amazonFTL) : bool
    {
        $data = $this->getTranslator()->objectToArray($amazonFTL, array('staff'));
        unset($data['data']['attributes']);
       
        $this->patch(
            $this->getResource().'/'.$amazonFTL->getId().'/freeze',
            $data
        );
        
        if ($this->isSuccess()) {
            $this->translateToObject($amazonFTL);
            return true;
        }

        return false;
    }

    public function unFreeze(AmazonFTL $amazonFTL) : bool
    {
        $data = $this->getTranslator()->objectToArray($amazonFTL, array('staff'));
        unset($data['data']['attributes']);
       
        $this->patch(
            $this->getResource().'/'.$amazonFTL->getId().'/unFreeze',
            $data
        );
        
        if ($this->isSuccess()) {
            $this->translateToObject($amazonFTL);
            return true;
        }

        return false;
    }

    protected function getNullParseTask() : INull
    {
        return NullParseTask::getInstance();
    }

    protected function getParseTaskRestfulTranslator() : ParseTaskRestfulTranslator
    {
        return new ParseTaskRestfulTranslator();
    }

    public function parse(ParseTask $parseTask) : bool
    {
        $data = $this->getParseTaskRestfulTranslator()->objectToArray($parseTask, array('fileName'));

        $this->post(
            $this->getResource().'/parse',
            $data
        );
        
        if ($this->isSuccess()) {
            $this->getParseTaskRestfulTranslator()->arrayToObject($this->getContents(), $parseTask);
            return true;
        }

        return false;
    }
    
    protected function getNullOrderPriceReport() : INull
    {
        return NullOrderPriceReport::getInstance();
    }

    protected function getOrderPriceReportRestfulTranslator() : OrderPriceReportRestfulTranslator
    {
        return new OrderPriceReportRestfulTranslator();
    }

    public function calculate(AmazonFTL $amazonFTL) : array
    {
        $keys = array(
            'pickupWarehouse',
            'targetWarehouse',
            'items',
            'pickupDate',
            'readyTime',
            'closeTime',
            'pickupAddressType',
            'deliveryAddressType',
            'member',
            'staff'
        );
        $data = $this->getTranslator()->objectToArray($amazonFTL, $keys);

        $this->post(
            'memberOrders/amazonFTL/calculate',
            $data
        );

        if ($this->isSuccess()) {
            return $this->getOrderPriceReportRestfulTranslator()->arrayToObjects($this->getContents());
        }

        return array(0, array());
    }

    public function fetchOneCalculateRecord($id)
    {
        $this->get('calculateRecords/'.$id);

        if ($this->isSuccess()) {
            return $this->getOrderPriceReportRestfulTranslator()->arrayToObject($this->getContents());
        }

        return $this->getNullOrderPriceReport();
    }
}
